using System;
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using static UnityEditor.PlayerSettings;

public class Agent : MonoBehaviour
{
    public Vector3 m_Pos;
    public Transform m_Transform;

    public Vector3 nowForce;
    public Vector3 nowSpeed;

    public GameObject Target;

    public Tuple<int,int,int> key;

    public int cnt = 0;
    void Start()
    {
        m_Transform=transform;
        m_Pos = transform.position;
        //nowSpeed = Random.insideUnitSphere * Random.Range(-maxSpeed, maxSpeed);

        key = AgentManager.instance.UpdateGridKey(m_Pos);
        AgentManager.instance.addAgent(key, gameObject);
        Target = GameObject.Find("Target");
        Debug.Log(key);
    }

    void Update()
    {
        //Debug.Log(key);
        Cluster();

        m_Transform.position += nowSpeed*Time.deltaTime;
        m_Pos = transform.position;
        AgentManager.instance.removeAgent(key, gameObject);
        key= AgentManager.instance.UpdateGridKey(m_Pos);
        AgentManager.instance.addAgent(key,gameObject);
        if(nowSpeed!=Vector3.zero)
        m_Transform.forward=nowSpeed.normalized;
        
    }

    public void Cluster()
    {
        Vector3 attrac = Vector3.zero;
        Vector3 reject = Vector3.zero;
        Vector3 align = Vector3.zero;
        Vector3 target = Vector3.zero;
       
        int agentcnt = 0;
        cnt = 0;
        for(int i=key.Item1-1; i<= key.Item1 + 1;i++)
        {
            for(int l=key.Item2-1;l<= key.Item2 + 1;l++)
            {
                for(int j=key.Item3-1;j<= key.Item3 + 1;j++)
                {
                    if (!AgentManager.instance.agentGridDictionary.ContainsKey(new(i, l, j)))
                    {
                        AgentManager.instance.agentGridDictionary.Add(new(i, l, j), new List<GameObject>());
                    }
                    foreach (GameObject Agent in AgentManager.instance.agentGridDictionary[new(i,l,j)])
                    {
                        if (Agent == this.gameObject)
                            continue;
                        float distance = Vector3.Distance(m_Pos, Agent.transform.position);
                        if (distance <= AgentManager.instance.responseRadius)
                        {
                            attrac += Agent.transform.position;

                            reject += (m_Pos - Agent.transform.position) / distance;

                            align += Agent.GetComponent<Agent>().nowSpeed;

                            agentcnt++;
                        }
                        cnt++;
                    }
                   
                }
            }
        }

        target = (Target.transform.position - m_Pos).normalized * AgentManager.instance.targetWeight;

        if(agentcnt > 0) 
        {
            attrac = (attrac/agentcnt-m_Pos) * AgentManager.instance.attractWeight;

            reject = reject * AgentManager.instance.rejectWeight;

            align=align.normalized * AgentManager.instance.alignWeight;
        }

        nowForce = attrac + reject + align + target;
        nowForce = Vector3.ClampMagnitude(nowForce, AgentManager.instance.maxSteeringForce);

        nowSpeed += nowForce * Time.deltaTime;

        nowSpeed= Vector3.ClampMagnitude(nowSpeed, AgentManager.instance.maxSpeed);
    }
}
